/**
 * Copyright 2010 Creative Works, Inc.
 * Creative Works licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.sendvox.freswitch.event.impl;

import java.util.Map;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.sendvox.freswitch.event.ChannelAnswerMessage;
import org.sendvox.freswitch.event.ChannelCallState;
import org.sendvox.freswitch.event.ChannelDataMessage;
import org.sendvox.freswitch.event.ChannelParkMessage;
import org.sendvox.freswitch.event.ChannelState;
import org.sendvox.freswitch.event.HeartbeatMessage;

public enum MessageFactory {

	INSTANCE;

	public HeartbeatMessage createHeartbeatMessage() {
		HeartbeatMessage heartbeatMessage = new HeartbeatMessage();
		return heartbeatMessage;
	}

	public ChannelAnswerMessage createChannelAnswerMessage(RawMessage rawMsg) {
		Map<Header, String> bodyMap = rawMsg.getEventBodyMap();
		ChannelAnswerMessage channelAnswerMsg = new ChannelAnswerMessage();
		populateChannelMessage(channelAnswerMsg, bodyMap);
		return channelAnswerMsg;
	}

	public ChannelParkMessage createChannelParkMessage(RawMessage response) {
		Map<Header, String> bodyMap = response.getEventBodyMap();
		ChannelParkMessage channelParkMsg = new ChannelParkMessage();
		populateChannelMessage(channelParkMsg, bodyMap);
		return channelParkMsg;
	}

	public ChannelDataMessage createChannelDataMessage(ChannelHandlerContext ctx, RawMessage response) {
		Map<Header, String> bodyMap = response.getEventBodyMap();
		ChannelDataMessage channelDataMsg = new ChannelDataMessage();
		populateChannelMessage(channelDataMsg, bodyMap);
		channelDataMsg.setChannelHandlerContext(ctx);
		channelDataMsg.setChannelDirection(bodyMap.get(Header.CHANNEL_DIRECTION).trim());
		channelDataMsg.setChannelDialplan(bodyMap.get(Header.CHANNEL_DIALPLAN).trim());
		channelDataMsg.setChannelCallerIDName(bodyMap.get(Header.CHANNEL_CALLER_ID_NAME).trim());
		channelDataMsg.setChannelCallerIDNumber(bodyMap.get(Header.CHANNEL_CALLER_ID_NUMBER).trim());
		channelDataMsg.setChannelNetworkAddr(bodyMap.get(Header.CHANNEL_NETWORK_ADDR).trim());
		channelDataMsg.setChannelDestinationNumber(bodyMap.get(Header.CHANNEL_DESTINATION_NUMBER).trim());
		channelDataMsg.setChannelUniqueID(bodyMap.get(Header.CHANNEL_UNIQUE_ID).trim());
		channelDataMsg.setChannelSource(bodyMap.get(Header.CHANNEL_SOURCE).trim());
		channelDataMsg.setChannelContext(bodyMap.get(Header.CHANNEL_CONTEXT).trim());
		channelDataMsg.setChannelChannelName(bodyMap.get(Header.CHANNEL_CHANNEL_NAME).trim());
		channelDataMsg.setChannelProfileIndex(Integer.parseInt(bodyMap.get(Header.CHANNEL_PROFILE_INDEX).trim()));
		channelDataMsg.setChannelProfileCreatedTime(bodyMap.get(Header.CHANNEL_PROFILE_CREATED_TIME).trim());
		channelDataMsg.setChannelChannelCreatedTime(bodyMap.get(Header.CHANNEL_CHANNEL_CREATED_TIME).trim());
		channelDataMsg.setChannelChannelAnsweredTime(bodyMap.get(Header.CHANNEL_CHANNEL_ANSWERED_TIME).trim());
		channelDataMsg.setChannelChannelProgressTime(bodyMap.get(Header.CHANNEL_CHANNEL_PROGRESS_TIME).trim());
		channelDataMsg.setChannelChannelProgressMediaTime(bodyMap.get(Header.CHANNEL_CHANNEL_PROGRESS_MEDIA_TIME).trim());
		channelDataMsg.setChannelChannelHangupTime(bodyMap.get(Header.CHANNEL_CHANNEL_HANGUP_TIME).trim());
		channelDataMsg.setChannelChannelTransferTime(bodyMap.get(Header.CHANNEL_CHANNEL_TRANSFER_TIME).trim());
		channelDataMsg.setChannelScreenBit(Boolean.parseBoolean(bodyMap.get(Header.CHANNEL_SCREEN_BIT).trim()));
		channelDataMsg.setChannelPrivacyHideName(Boolean.parseBoolean(bodyMap.get(Header.CHANNEL_PRIVACY_HIDE_NAME).trim()));
		channelDataMsg.setChannelPrivacyHideNumber(Boolean.parseBoolean(bodyMap.get(Header.CHANNEL_PRIVACY_HIDE_NUMBER).trim()));
		return channelDataMsg;
	}

	private void populateChannelMessage(ChannelMessage channelMsg,
			Map<Header, String> bodyMap) {
		this.populateMessage(channelMsg, bodyMap);

		channelMsg.setChannelState(ChannelState.fromLiteral(bodyMap.get(Header.CHANNEL_STATE).trim()));
		channelMsg.setChannelCallState(ChannelCallState.fromLiteral(bodyMap.get(Header.CHANNEL_CALL_STATE).trim()));
		channelMsg.setChannelStateNumber(Integer.parseInt(bodyMap.get(Header.CHANNEL_STATE_NUMBER).trim()));
		channelMsg.setChannelName(bodyMap.get(Header.CHANNEL_NAME).trim());
		channelMsg.setUniqueID(bodyMap.get(Header.UNIQUE_ID).trim());
		channelMsg.setCallDirection(bodyMap.get(Header.CALL_DIRECTION).trim());
		channelMsg.setPresenceCallDirection(bodyMap.get(Header.PRESENCE_CALL_DIRECTION).trim());
		channelMsg.setChannelPresenceID(bodyMap.get(Header.CHANNEL_PRESENCE_ID).trim());
		channelMsg.setChannelCallUUID(bodyMap.get(Header.CHANNEL_CALL_UUID).trim());
		channelMsg.setAnswerState(ChannelCallState.fromLiteral(bodyMap.get(Header.ANSWER_STATE).trim()));
		channelMsg.setChannelReadCodecName(bodyMap.get(Header.CHANNEL_READ_CODEC_NAME).trim());
		channelMsg.setChannelReadCodecRate(Integer.parseInt(bodyMap.get(Header.CHANNEL_READ_CODEC_RATE).trim()));
		channelMsg.setChannelReadCodecBitRate(Integer.parseInt(bodyMap.get(Header.CHANNEL_READ_CODEC_BIT_RATE).trim()));
		channelMsg.setCallerDirection(bodyMap.get(Header.CALLER_DIRECTION).trim());
		channelMsg.setCallerCallerIDNumber(bodyMap.get(Header.CALLER_CALLER_ID_NUMBER).trim());
		channelMsg.setCallerCalleeIDNumber(bodyMap.get(Header.CALLER_CALLEE_ID_NUMBER));
		channelMsg.setCallerCalleeIDName(bodyMap.get(Header.CALLER_CALLEE_ID_NAME));
		channelMsg.setCallerNetworkAddr(bodyMap.get(Header.CALLER_NETWORK_ADDR).trim());
		channelMsg.setCallerDestinationNumber(bodyMap.get(Header.CALLER_DESTINATION_NUMBER).trim());
		channelMsg.setCallerUniqueID(bodyMap.get(Header.CALLER_UNIQUE_ID).trim());
		channelMsg.setCallerSource(bodyMap.get(Header.CALLER_SOURCE).trim());
		channelMsg.setCallerContext(bodyMap.get(Header.CALLER_CONTEXT).trim());
		channelMsg.setCallerChannelName(bodyMap.get(Header.CALLER_CHANNEL_NAME).trim());
		channelMsg.setCallerProfileIndex(Integer.parseInt(bodyMap.get(Header.CALLER_PROFILE_INDEX).trim()));
		channelMsg.setCallerProfileCreatedTime(bodyMap.get(Header.CALLER_PROFILE_CREATED_TIME).trim());
		channelMsg.setCallerChannelCreatedTime(bodyMap.get(Header.CALLER_CHANNEL_CREATED_TIME).trim());
		channelMsg.setCallerChannelAnsweredTime(bodyMap.get(Header.CALLER_CHANNEL_ANSWERED_TIME).trim());
		channelMsg.setCallerChannelProgressTime(bodyMap.get(Header.CALLER_CHANNEL_PROGRESS_TIME).trim());
		channelMsg.setCallerChannelProgressMediaTime(bodyMap.get(Header.CALLER_CHANNEL_PROGRESS_MEDIA_TIME).trim());
		channelMsg.setCallerChannelHangupTime(bodyMap.get(Header.CALLER_CHANNEL_HANGUP_TIME).trim());
		channelMsg.setCallerChannelTransferTime(bodyMap.get(Header.CALLER_CHANNEL_TRANSFER_TIME).trim());
		channelMsg.setCallerScreenBit(Boolean.parseBoolean(bodyMap.get(Header.CALLER_SCREEN_BIT).trim()));
		channelMsg.setCallerPrivacyHideName(Boolean.parseBoolean(bodyMap.get(Header.CALLER_PRIVACY_HIDE_NAME).trim()));
		channelMsg.setCallerPrivacyHideNumber(Boolean.parseBoolean(bodyMap.get(Header.CALLER_PRIVACY_HIDE_NAME).trim()));

	}

	private void populateMessage(Message msg, Map<Header, String> bodyMap) {
		msg.setCoreUUID(bodyMap.get(Header.CORE_UUID).trim());
		msg.setFreeSwitchHostname(bodyMap.get(Header.FREESWITCH_HOSTNAME).trim());
		msg.setFreeSwitchSwitchname(bodyMap.get(Header.FREESWITCH_SWITCHNAME).trim());
		msg.setFreeSwitchIPv4(bodyMap.get(Header.FREESWITCH_IPV4).trim());
		msg.setFreeSwitchIPv6(bodyMap.get(Header.FREESWITCH_IPV6).trim());
		msg.setEventDateLocal(bodyMap.get(Header.EVENT_DATE_LOCAL).trim());
		msg.setEventDateGMT(bodyMap.get(Header.EVENT_DATE_GMT).trim());
		msg.setEventDateTimestamp(bodyMap.get(Header.EVENT_DATE_TIMESTAMP).trim());
		msg.setEventCallingFile(bodyMap.get(Header.EVENT_CALLING_FILE).trim());
		msg.setEventCallingFunction(bodyMap.get(Header.EVENT_CALLING_FUNCTION).trim());
		msg.setEventCallingLineNumber(Integer.parseInt(bodyMap.get(Header.EVENT_CALLING_LINE_NUMBER).trim()));
	}

}
